package org.example.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.example.mapper.LogMapper;
import org.example.pojo.LogVO;
import org.example.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

import static org.example.utils.IpUtil.getClientIp;

@Aspect
@Component
public class LogAspect {

    @Autowired
    private LogMapper logMapper;

    @Around("@annotation(org.example.utils.Loggable)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取请求对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        // 获取注解
        Loggable loggable = method.getAnnotation(Loggable.class);
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        String username = null;
        // 如果是登录方法，从参数中提取用户名
        if ("登录".equals(loggable.action())) {
            for (Object arg : args) {
                if (arg.toString().contains("User")) {
                    User user = (User) arg;
                    username = user.getUsername();
                    break;
                }
            }
        } else {
            // 从请求头中获取Token
            String token = request.getHeader("Authorization");
            // 从Token中获取用户名
            if (token != null) {
                username = Jwt.getUsernameFromToken(token);
            }
        }



        // 获取操作者IP
        String ip = getClientIp(request);

        // 获取操作行为
        String action = loggable.action();

        // 执行方法
        Result result = (Result) joinPoint.proceed();

        // 记录操作结果
        String operationResult = "";
        if (result.isSucceed()) {
            operationResult = "成功";
        } else {
            operationResult = "失败";
        }

        // 创建日志对象
        LogVO log = new LogVO();
        log.setUsername(username);
        log.setIp(ip);
        log.setAction(action);
        log.setResult(operationResult);

        // 保存日志
        logMapper.addLog(log);

        return result;
    }
}